在build專案的時候,我們會透過webpack將不同模組的component打包成同一支js,但是當專案的規模越來越大, 程式碼的size就會逐漸肥大,好幾mb都有可能,載入的時間也會拉長,影響使用者體驗,而且並非所有的程式碼的功能會在一開始就使用到,所以透過React lazy可以將程式碼拆分成不同的區塊延遲載入,優先載入比較重要的js, 再載入次要的js,就不需要一口氣載入全部的程式碼了!
React Suspense & React Lazy為 16.6的版本才有的功能
React lazy 和 React suspense 還沒有辦法在SSR(server-side)使用 ,如果有程式碼切割的需求就必須使用 Loadable Components
根據官網的描述,如果你的專案適用以下這三種方式建立的,那麼已經有webpack的設定
動態載入js,可以將程式碼分割,需要用到時再用import載入
延遲載入component會被suspense包覆 ,假如component還沒載入完成, 就能夠透過fallback顯示一些提示訊息,必須搭配Lazy使用,如果只有寫Lazy沒有Suspense的話就會報錯,另外,Suspense可以包覆多個lazy component
以下的例子是動態載入ToDoList
import React, { Suspense, lazy, Fragment } from 'react'
const TodoList = lazy(() => import('./TodoList'));
const LazyExample = () => {
return (
<Fragment>
<Suspense fallback={<p>Loading~~~~</p>}>
<TodoList />
</Suspense>
</Fragment>
)
}
export default LazyExample
可以利用google dev tools,利用network來模擬網速慢的狀況,網速選slow 3G,就能夠看到在載入ToDoList之前看到loading的字樣。
觀察network載入的檔案,會發現多了一個1.chunk.js,其實也就是ToDoList
但如果延遲載入的js很多,這樣的命名方式就不太好辨識哪個js檔案對應的是哪一個模組,可以再加上註解webpackChunkName,這樣切割出來bundle的檔名就會依照註解的名稱命名
const TodoList = lazy(() => import(/* webpackChunkName: "toDoList" */'./TodoList'));
可以看到原本的1.chunk.js變成toDoList.chunk.js
如果有一些不常用到的功能就可以被切割出來,畢竟在這個分秒必爭的時代,加速網頁載入速度是很重要的優化項目,或許你會想問現在大家都網路速度都很快,有差一點那麼一點時間嗎?答案是肯定的,因為你無法確定所有人的網路環境都很好,以我自身在租屋處的例子,網路忽快忽慢,慢的時候隨便打開一個網頁都要等個三十秒,更何況是js檔案很肥大的網頁,真的是考驗人的耐性,所以減少網頁載入的時間絕對是有必要的。